package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.constant.MessageConstant;
import com.itheima.entity.Result;
import com.itheima.pojo.*;
import com.itheima.service.MemberService;
import com.itheima.service.OrderService;
import com.itheima.service.ReportService;
import com.itheima.service.SetmealService;
import com.itheima.utils.DateUtils;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * 统计报表
 */

@RestController
@RequestMapping("/report")
public class ReportController {
    @Reference
    private MemberService memberService;
    @Reference
    private SetmealService setmealService;
    @Reference
    private OrderService orderService;

    //获取会员数量统计数据
    @RequestMapping("/getMemberReport")
    public Result getMemberReport() {
        try {
            //动态获取过去1年的12个月，并封装到集合中
            List<String> months = new ArrayList<>();
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -12);//add方法用于计算
            for (int i = 0; i < 12; i++) {
                calendar.add(Calendar.MONTH, 1);//add方法用于计算
                months.add(DateUtils.parseDate2String(calendar.getTime(), "yyyy.MM"));
            }
            //根据月份查询对应的会员数量
            List<Integer> memberCount = memberService.findMemberCountByMonths(months);

            Map<String, Object> data = new HashMap<>();
            data.put("months", months);
            data.put("memberCount", memberCount);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, data);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    //获取套餐占比统计数据
    @RequestMapping("/getSetmealReport")
    public Result getSetmealReport() {
        try {
            List<String> setmealNames = new ArrayList<>();//封装套餐名称集合
            List<Map> setmealCount = setmealService.getSetmealReport();//套餐名称和预约数量集合
            if (setmealCount != null && setmealCount.size() > 0) {
                for (Map map : setmealCount) {
                    String name = (String) map.get("name");//套餐名称
                    setmealNames.add(name);
                }
            }

            Map<String, Object> map = new HashMap<>();
            map.put("setmealNames", setmealNames);
            map.put("setmealCount", setmealCount);
            return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

    //每日预约数、每日到诊数(作废)
    @RequestMapping("/order_diagosised")
    public Result getOrder_Diagosised() {
        try {
            //动态获取过去1年的12个月，并封装到集合中
            List<String> months = new ArrayList<>();
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -12);//add方法用于计算
            for (int i = 0; i < 12; i++) {
                calendar.add(Calendar.MONTH, 1);//add方法用于计算
                months.add(DateUtils.parseDate2String(calendar.getTime(), "yyyy.MM"));
            }
            //根据月份查询对应的会员数量
            List<Integer> memberCount = orderService.findOrderByMonths(months);

            Map<String, Object> data = new HashMap<>();
            data.put("months", months);
            data.put("memberCount", memberCount);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, data);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    //每日预约数、每日到诊数
    @RequestMapping("/order_diagosised1")
    public Result getOrder_Diagosised1() throws Exception {
        try {
            List<Order> allOrders = orderService.findAllOrders();
            //System.out.println("service中查到的orderList==" + allOrders);
            //LinkedHashSet 有序存入日期
            LinkedHashSet<String> set = new LinkedHashSet<>();
            Map<String, Object> data = new HashMap<>();
            for (Order order : allOrders) {
                Date orderDate = order.getOrderDate();
                String date = DateUtils.parseDate2String(orderDate, "yyyy.MM.dd");
                set.add(date);
            }
            //System.out.println("set中的date==" + set);
            //根据日期查当日新增预约数
            List<Integer> orderCounts = orderService.findOrderCountByDate(set);
            //根据日期查当日到诊数
            List<Integer> diagnosised = orderService.findDiagnosisedByDate(set);
            List<String> dates = new ArrayList<>(set);
            //System.out.println("list中的date==" + dates);
            data.put("memberCount", orderCounts);
            data.put("date", dates);
            data.put("diagnosised", diagnosised);
            return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS, data);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MEMBER_NUMBER_REPORT_FAIL);
        }
    }

    //体检收入
    @RequestMapping("/income")
    public Result income(String value) {
        try {
            //value="2019-12-03 - 2020-01-19" 分割字符串得到
            //2019-12-03 , - , 2020-01-19 取索引0,2
            System.out.println("页面中获取的时间"+value);
            String[] s = value.split(" ");
            String startDate = s[0];
            //System.out.println(startDate);
            String endDate = s[2];
            //System.out.println(endDate);
            Map<String,String> dateMap = new HashMap<>();
            dateMap.put("startDate" , startDate);
            dateMap.put("endDate" , endDate);
            List<String> names = new ArrayList<>();//封装套餐名称
            List<Map> namesAndIncomes = setmealService.findIncomeByDate(dateMap);//套餐名称和预约数量集合
            Double count = 0d;
            for (Map namesAndIncome : namesAndIncomes) {
                Double price = (Double) namesAndIncome.get("value");
                //System.out.println(price);
                count += price;
            }
            Map<String, Object> zonghe = new HashMap<>();
            zonghe.put("name", "总收入");
            zonghe.put("value", count);
            namesAndIncomes.add(zonghe);
            //获得时间段内的套餐名
            for (Map namesAndIncome : namesAndIncomes) {
                String o = (String) namesAndIncome.get("name");
                names.add(o);
            }
            Map<String, Object> map = new HashMap<>();
            map.put("incomeNames",names);
            map.put("incomeValue",namesAndIncomes);
            //System.out.println(map);
            return new Result(true, MessageConstant.GET_SETMEAL_COUNT_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_SETMEAL_COUNT_REPORT_FAIL);
        }
    }

    //年龄分布
    @RequestMapping("/memberAge")
    public Result memberAge(){
        List<Integer> list = orderService.memberAge();
        System.out.println(list);
        List<String> list1 = new ArrayList<>();
        list1.add("婴儿(0-6岁)");
        list1.add("少年(7-12岁)");
        list1.add("青少年(13-17岁)");
        list1.add("青年(18-45岁)");
        list1.add("中年(46-69)");
        list1.add("老年(大于69岁)");
        Map<String,Object> map = new HashMap<>();
        map.put("memberCount",list);
        map.put("age",list1);
        return new Result(true,"成功",map);
    }

    @Reference
    private ReportService reportService;

    //获取运营统计数据
    @RequestMapping("/getBusinessReportData")
    public Result getBusinessReportData() {
        try {
            Map<String, Object> map = reportService.getBusinessReportData();
            return new Result(true, MessageConstant.GET_BUSINESS_REPORT_SUCCESS, map);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    //导出运营数据到Excel并提供客户端下载
    @RequestMapping("/exportBusinessReport")
    public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response) {
//        request.getServletContext().getRealPath("/template");
        try {
            Map<String, Object> result = reportService.getBusinessReportData();

            //取出返回结果数据，准备将报表数据写入到Excel文件中
            String reportDate = (String) result.get("reportDate");
            Integer todayNewMember = (Integer) result.get("todayNewMember");
            Integer totalMember = (Integer) result.get("totalMember");
            Integer thisWeekNewMember = (Integer) result.get("thisWeekNewMember");
            Integer thisMonthNewMember = (Integer) result.get("thisMonthNewMember");
            Integer todayOrderNumber = (Integer) result.get("todayOrderNumber");
            Integer thisWeekOrderNumber = (Integer) result.get("thisWeekOrderNumber");
            Integer thisMonthOrderNumber = (Integer) result.get("thisMonthOrderNumber");
            Integer todayVisitsNumber = (Integer) result.get("todayVisitsNumber");
            Integer thisWeekVisitsNumber = (Integer) result.get("thisWeekVisitsNumber");
            Integer thisMonthVisitsNumber = (Integer) result.get("thisMonthVisitsNumber");
            List<Map> hotSetmeal = (List<Map>) result.get("hotSetmeal");

            //动态获取Excel模板文件绝对磁盘路径
//            request.getserv
            String filePath = request.getSession().getServletContext().getRealPath("/template") + File.separator + "report_template.xlsx";

            //基于POI在内存中创建一个Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File(filePath)));

            XSSFSheet sheet = excel.getSheetAt(0);

            XSSFRow row = sheet.getRow(2);
            row.getCell(5).setCellValue(reportDate);//日期

            row = sheet.getRow(4);
            row.getCell(5).setCellValue(todayNewMember);//新增会员数（本日）
            row.getCell(7).setCellValue(totalMember);//总会员数

            row = sheet.getRow(5);
            row.getCell(5).setCellValue(thisWeekNewMember);//本周新增会员数
            row.getCell(7).setCellValue(thisMonthNewMember);//本月新增会员数

            row = sheet.getRow(7);
            row.getCell(5).setCellValue(todayOrderNumber);//今日预约数
            row.getCell(7).setCellValue(todayVisitsNumber);//今日到诊数

            row = sheet.getRow(8);
            row.getCell(5).setCellValue(thisWeekOrderNumber);//本周预约数
            row.getCell(7).setCellValue(thisWeekVisitsNumber);//本周到诊数

            row = sheet.getRow(9);
            row.getCell(5).setCellValue(thisMonthOrderNumber);//本月预约数
            row.getCell(7).setCellValue(thisMonthVisitsNumber);//本月到诊数

            int rowNum = 12;
            for (Map map : hotSetmeal) {//热门套餐
                String name = (String) map.get("name");
                Long setmeal_count = (Long) map.get("setmeal_count");
                BigDecimal proportion = (BigDecimal) map.get("proportion");
                row = sheet.getRow(rowNum++);
                row.getCell(4).setCellValue(name);//套餐名称
                row.getCell(5).setCellValue(setmeal_count);//预约数量
                row.getCell(6).setCellValue(proportion.doubleValue());//占比
            }

            //创建输出流，用于从服务器写数据到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;filename=report.xlsx");
            excel.write(out);

            out.flush();
            out.close();
            excel.close();

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    //导出运营数据到PDF文件并提供客户端下载
    @RequestMapping("/exportBusinessReport4PDF")
    public Result exportBusinessReport4PDF(HttpServletRequest request, HttpServletResponse response) {
        try {
            Map<String, Object> result = reportService.getBusinessReportData();

            //取出返回结果数据，准备将报表数据写入到Excel文件中
            List<Map> hotSetmeal = (List<Map>) result.get("hotSetmeal");

            //动态获取pdf模板文件绝对磁盘路径
            String jrxmlPath = request.getSession().getServletContext().getRealPath("template") + File.separator + "health_business3.jrxml";
            String jasperPath = request.getSession().getServletContext().getRealPath("template") + File.separator + "health_business3.jasper";

            //编译模板
            JasperCompileManager.compileReportToFile(jrxmlPath, jasperPath);

            //填充数据---使用JavaBean数据源方式填充
            JasperPrint jasperPrint =
                    JasperFillManager.fillReport(jasperPath, result,
                            new JRBeanCollectionDataSource(hotSetmeal));

            //创建输出流，用于从服务器写数据到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            response.setContentType("application/pdf");
            response.setHeader("content-Disposition", "attachment;filename=report.pdf");

            //输出文件
            JasperExportManager.exportReportToPdfStream(jasperPrint, out);

            out.flush();
            out.close();

            return null;
        }catch (Exception e){
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }

    //导出会员信息数据到Excel并提供客户端下载
    //数据包含会员预约信息
    @RequestMapping("/exportMemberReport")
    public Result exportMemberReport(HttpServletRequest request, HttpServletResponse response,Integer[] memberIds){

        try{
          List<Map<String,Object>> result = reportService.getMemberReportData(memberIds);

            //动态获取Excel模板文件绝对磁盘路径
//            request.getserv
            String filePath = request.getSession().getServletContext().getRealPath("/template") + File.separator + "MemberMessage.xlsx";

            //基于POI在内存中创建一个Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File(filePath)));

            XSSFSheet sheet = excel.getSheetAt(0);

           //取出返回结果数据，准备将报表数据写入到Excel文件中


            //遍历result集合
          List <Map<String, String>> xiuGai=new ArrayList<Map<String, String>>();

            for (int i = 0; i < result.size(); i++) {
                //取出"member"键对应的值member对象
                Member member = (Member) result.get(i).get("member");
                String name = member.getName();
                String sex = member.getSex();
                String phoneNumber = member.getPhoneNumber();
                List<Map<Setmeal,String>> addressAndSetMeal = (List) result.get(i).get("addressAndSetMeal");
                for (int j = 0; j < addressAndSetMeal.size();j++) {
                    Map<String,String> xiuGaiMap=new HashMap<String,String>();
                    String address = "";
                    String CheckGroupColumnName ="";
                    String CheckItemColumnName ="";
                    String setmealName="";
                    Set<Map.Entry<Setmeal, String>> entries = addressAndSetMeal.get(j).entrySet();
                    for (Map.Entry<Setmeal, String> set : entries) {
                        address = set.getValue();
                        Setmeal setmeal = set.getKey();
                        setmealName = setmeal.getName();
                        List<CheckGroup> checkGroups = setmeal.getCheckGroups();
                        for (CheckGroup checkGroup : checkGroups) {
                            String checkGroupName = checkGroup.getName();
                            CheckGroupColumnName=CheckGroupColumnName + checkGroupName+",";
                            List<CheckItem> checkItems = checkGroup.getCheckItems();
                            for (CheckItem checkItem : checkItems) {
                                String checkItemName = checkItem.getName();
                                CheckItemColumnName=CheckItemColumnName+checkItemName+",";
                            }
                        }
                    }
                    xiuGaiMap.put("name",name);
                    if (sex.equals("1")){
                        xiuGaiMap.put("sex","男");
                    }else{
                        xiuGaiMap.put("sex","女");
                    }

                    xiuGaiMap.put("phoneNumber",phoneNumber);
                    xiuGaiMap.put("address",address);
                    xiuGaiMap.put("setmealName",setmealName);
                    xiuGaiMap.put("CheckGroupColumnName",CheckGroupColumnName);
                    xiuGaiMap.put("CheckItemColumnName",CheckItemColumnName);
                    xiuGai.add(xiuGaiMap);

//                    row.createCell(0).setCellValue(name);
//                    row.createCell(1).setCellValue(sex);
//                    row.createCell(2).setCellValue(phoneNumber);
//                    row.createCell(3).setCellValue(address);
//                    row.createCell(4).setCellValue(setmealName);
//                    row.createCell(5).setCellValue(CheckGroupColumnName);
//                    row.createCell(6).setCellValue(CheckItemColumnName);
                }
            }
            for (int i = 0; i < xiuGai.size(); i++) {
                XSSFRow row = sheet.createRow(i+3);
                Map<String, String> map = xiuGai.get(i);
                row.createCell(0).setCellValue(map.get("name"));
                row.createCell(1).setCellValue(map.get("sex"));
                row.createCell(2).setCellValue(map.get("phoneNumber"));
                row.createCell(3).setCellValue(map.get("address"));
                row.createCell(4).setCellValue(map.get("setmealName"));
                row.createCell(5).setCellValue(map.get("CheckGroupColumnName"));
                row.createCell(6).setCellValue(map.get("CheckItemColumnName"));

            }


            //创建输出流，用于从服务器写数据到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("content-Disposition", "attachment;filename=report.xlsx");
            excel.write(out);

            out.flush();
            out.close();
            excel.close();

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL);
        }
    }
}
